#include <iostream>
#include "ALooper.h"
#include "AMessage.h"
#include "AHandler.h"
#include "log.h"

#define LOG_TAG "main"
using namespace std;

class A : public AHandler {
public:
    A() = default;

    void init() {
        mLooper = ALooper::Create();
        mLooper->registerHandler(shared_from_this());
        mLooper->start();
        LOGI("init done");
    }

    shared_ptr<AMessage> initSync(int param1, double param2) {
        LOGI(">>");
        shared_ptr<AMessage> msg = AMessage::Create(kWhatInit, shared_from_this());
        msg->setValue("param1", param1);
        msg->setValue("param2", param2);
        shared_ptr<AMessage> response;
        msg->postAndAwaitResponse(&response);
        int i;
        msg->getValue("haha", &i);
        LOGI("got response %d", i);
        return response;
    }

    void startAsync(int param1, double param2) {
        LOGI(">>");
        shared_ptr<AMessage> msg = AMessage::Create(kWhatStart, shared_from_this());
        msg->setValue("param1", param1);
        msg->setValue("param2", param2);
        msg->post();
    }

private:
    enum {
        kWhatInit,
        kWhatStart,
    };

    void onMessageReceived(const std::shared_ptr<AMessage> &msg) override {
        switch (msg->what()) {
            case kWhatInit: {
                int param1;
                msg->getValue("param1", &param1);
                double param2;
                msg->getValue("param2", &param2);
                LOGI("param1 %d, param2 %.3f", param1, param2);
                shared_ptr<AReplyToken> replyToken;
                msg->senderAwaitsResponse(&replyToken);
                shared_ptr<AMessage> response = AMessage::Create();
                response->setValue<int>("haha", 1);
                response->postReply(replyToken);
                break;
            }
            case kWhatStart: {
                int param1;
                msg->getValue("param1", &param1);
                double param2;
                msg->getValue("param2", &param2);
                LOGI("param1 %d, param2 %.3f", param1, param2);
                break;
            }
        }
    }

    shared_ptr<ALooper> mLooper;
};


int main() {
    shared_ptr<A> a = make_shared<A>();
    a->init();
    LOGI("init done");
    a->initSync(2, 3.5);
    LOGI("initSync done");
    a->startAsync(4, 6.1);
    return 0;
}
